package com.itheima.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.conmmon.BaseContext;
import com.itheima.conmmon.CustomException;
import com.itheima.conmmon.R;
import com.itheima.domain.Category;
import com.itheima.domain.Dish;
import com.itheima.domain.Setmeal;
import com.itheima.domain.SetmealDish;
import com.itheima.dto.SetMealWithDishDto;
import com.itheima.dto.SetmealDto;
import com.itheima.service.CategoryService;
import com.itheima.service.DishService;
import com.itheima.service.SetMealService;
import com.itheima.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * @author liwanhu
 * @datetime 2021/10/28 9:35
 */
@RestController
@RequestMapping("setmeal")
@Slf4j
public class SetMealController {
    @Autowired
    private SetMealService setMealService;
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishService dishService;

    /**
     * 添加套餐
     *
     * @param setmealDto
     * @return
     */
    @PostMapping
    @CacheEvict(value = "setMealCache",allEntries = true)
    public R<String> get(@RequestBody SetmealDto setmealDto) {
        log.info("套餐添加的数据 {}",setmealDto.toString());
        setMealService.saveGetDish(setmealDto);
        return R.success("添加套餐成功");
    }

    /**
     * 分页查询套餐,以及套餐分类的名称
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("page")
    public R<Page> page(int page, int pageSize, String name) {
        //创建 分页构造器
        Page<Setmeal> pageInfo = new Page<>(page, pageSize);

        //新建一个分页构造器,将泛型数据写为SetmealDto实体类,因为它封装的数据更具体
        Page<SetmealDto> dtoPage = new Page<>();

        //创建 条件构造器
        QueryWrapper<Setmeal> queryWrapper = new QueryWrapper<>();

        //判断套餐不名字不为空才获取
        queryWrapper.like(name != null, "name", name);
        queryWrapper.orderByDesc("update_time");
        setMealService.page(pageInfo,queryWrapper);

        //将pageInfo里面的数据拷贝到dtoPage中,除了records数据因为pageInfo中的records数据不完整,不能供前端页面要的完整数据
        BeanUtils.copyProperties(pageInfo, dtoPage, "records");

        //获取pageInfo对象中的records数据
        List<Setmeal> records = pageInfo.getRecords();
        //遍历records对象,并对其进行传入套餐分类的名称
        List<SetmealDto> list = records.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();

            //在records数据中获取到分类的id
            Long categoryId = item.getCategoryId();
            BeanUtils.copyProperties(item,setmealDto);

            //调用分类的业务层方法通过id获取到分类对象
            Category category = categoryService.getById(categoryId);

            if (category != null) {
                //获取分类的套餐名称
                String categoryName = category.getName();
                //将套餐分类名称塞到setMealDto对象中
                setmealDto.setCategoryName(categoryName);
            }
            return setmealDto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(list);
        return R.success(dtoPage);
    }

    /**
     * 根据套餐ID删除套餐
     * @param ids
     * @return
     */
    @DeleteMapping
    @CacheEvict(value = "setMealCache",allEntries = true)//value要删除的缓存名称,删除value名称下所有的缓存数据
    public R<String> deleteSetMeal(@RequestParam List<Long> ids){
        log.info("根据id删除套餐",ids);
        setMealService.deleteWithDish(ids);
        return R.success("删除成功");
    }

    /**
     * 查询套餐信息
     * @param setmeal
     * @return
     */
    @GetMapping("list")
    @Cacheable(value = "setMealCache",key = "#setmeal.categoryId + '_' + #setmeal.status")
    public R<List<Setmeal>> list(Setmeal setmeal){
        //创建条件构造器
        QueryWrapper<Setmeal> queryWrapper = new QueryWrapper<>();
        //查询套餐所对应的分类
        queryWrapper.eq(setmeal.getCategoryId() !=null,"category_id",setmeal.getCategoryId());
        queryWrapper.eq(setmeal.getStatus() !=null,"status",setmeal.getStatus());
        queryWrapper.orderByDesc("update_time");
        //获取所有套餐对象
        List<Setmeal> list = setMealService.list(queryWrapper);
        //将数据返回到页面
        return R.success(list);
    }

    /**
     * 实战第一天
     *显示套餐
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<SetmealDto> update(@PathVariable Long id){
        SetmealDto setmealDto = setMealService.updateWithSetMeal(id);
        return R.success(setmealDto);
    }

    /**
     * 实战第一天
     * 修改套餐信息
     * @param setmealDto
     * @return
     */

    @PutMapping
    @CacheEvict(value = "setMealCache",allEntries = true)
    public R<String> put(@RequestBody SetmealDto setmealDto){
        setMealService.updateWithDish(setmealDto);
        return R.success("修改成功");
    }

    /**
     * 实战第一天
     * 修改套餐的启停状态
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("status/{status}")
    public R<String> status(@PathVariable Integer status, @RequestParam  List<Long> ids){
        for (int i = 0; i < ids.size(); i++) {
            //查询前端穿来的id是否是套餐表中存在的,存在时修改套餐的状态
            UpdateWrapper<Setmeal> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id",ids.get(i));
            updateWrapper.set("status",status);
            //查询套餐菜品的信息,查询属于套餐的菜品信息
            QueryWrapper<SetmealDish> setmealDishQueryWrapper = new QueryWrapper<>();
            setmealDishQueryWrapper.eq("setmeal_id",ids.get(i));
            //因为套餐中有多个菜品所以用list
            List<SetmealDish> list = setmealDishService.list(setmealDishQueryWrapper);
            //查询菜品
            for (SetmealDish setmealDish : list) {
                //获取菜品信息
                Dish dish = dishService.getById(setmealDish.getDishId());
                //获取菜品的状态
                Integer status1 = dish.getStatus();
                if (status1 == 0 ){
                    throw new CustomException("菜品已停售,套餐不能启售");
                }
            }
            setMealService.update(updateWrapper);
        }
        return R.success("修改套餐状态成功");
    }
    /**
     * 实战第一天
     * 查看套餐内容
     * @param id
     * @return
     */
    @GetMapping("/dish/{id}")
    public R<List<SetMealWithDishDto>> list(@PathVariable Long id){
        log.info(id.toString());
        //条件构造器查询套餐对应的菜品
        QueryWrapper<SetmealDish> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("setmeal_id",id);
        //获取菜品集合
        List<SetmealDish> list = setmealDishService.list(queryWrapper);
        //遍历菜品集合
        List<SetMealWithDishDto> list1 = list.stream().map((item) -> {
            SetMealWithDishDto setMealWithDishDto = new SetMealWithDishDto();
            //将菜品对象拷贝到setMealWithDishDto
            BeanUtils.copyProperties(item, setMealWithDishDto);
            //获取菜品id
            Long dishId = item.getDishId();
            //获取菜品对象
            Dish dish = dishService.getById(dishId);
            //获取图片uri
            String image = dish.getImage();
            //存入对象中
            setMealWithDishDto.setImage(image);
            return setMealWithDishDto;
        }).collect(Collectors.toList());
        return R.success(list1);
    }
}
